<?php

    #-------------------------------------------------------------#
	# This file is part of the Tekuna MVC Microframework for PHP. #
	# (c) 2009 Niels Jäckel <niels.jaeckel@tekuna.org>            #
	# Please visit http://tekuna.org/ for more information.       #
	#                                                             #
	# This software is licensed under the MIT License. Please     #
	# view the LICENSE file for the full text of this license.    #
    #-------------------------------------------------------------#


	Tekuna :: load('org.tekuna.test.testApplication.components.controller.TestMVCController');
	Tekuna :: load('org.tekuna.test.testApplication.components.controller.TestMinimalMVCController');
	Tekuna :: load('org.tekuna.test.testApplication.components.controller.TestXSLTMVCController');
	Tekuna :: load('org.tekuna.test.testApplication.components.controller.TestPHPMVCController');
	Tekuna :: load('org.tekuna.test.testApplication.components.controller.TestMVCNoI18NController');
	Tekuna :: load('org.tekuna.test.testApplication.components.controller.TestMVCModelController');

	Tekuna :: load('org.tekuna.test.core.helper.RequestMock');
	Tekuna :: load('org.tekuna.test.testApplication.components.controller.TestMVCDisplayController');
	Tekuna :: load('org.tekuna.test.testApplication.components.controller.TestMVCValidateFalseController');
	Tekuna :: load('org.tekuna.test.testApplication.components.controller.TestMVCValidateTrueController');
	Tekuna :: load('org.tekuna.test.testApplication.components.controller.TestMVCValidateFalseExceptionController');
	Tekuna :: load('org.tekuna.test.testApplication.components.controller.TestMVCRedirectSourceController');


	Tekuna :: load('org.tekuna.test.testApplication.components.model.TestModel');
	Tekuna :: load('org.tekuna.test.testApplication.components.model.TestMVCModelControllerModel');


	class MVCControllerTest extends AbstractTekunaTestCase {

		protected function buildContext() {

			$objContext = new TekunaApplicationContext();
			$objContext -> setRequest(new Request());
			$objContext -> setResponse(new Response());
			$objContext -> setURLInformation(new URLInformation());
			$objContext -> setClientInformation(new ClientInformation());
			$objContext -> setApplicationLanguage('en-us');

			return $objContext;
		}


		protected function getMVCController() {

			return new TestMVCController($this -> buildContext());
		}


		protected function getXSLTMVCController() {

			return new TestXSLTMVCController($this -> buildContext());
		}


		protected function getPHPMVCController() {

			return new TestPHPMVCController($this -> buildContext());
		}


		protected function getMVCNoI18NController() {

			return new TestMVCNoI18NController($this -> buildContext());
		}


		protected function getMVCModelController() {

			return new TestMVCModelController($this -> buildContext());
		}


		public function testGettersSetters() {

			// create controller instance
			$objController = $this -> getMVCController();

			// test getters and setters
			$objModel = new TestModel();
			$objController -> useModel($objModel);
			$this -> assertIdentical($objController -> getModel(), $objModel);

			$objView = new SimpleView();
			$objController -> useView($objView);
			$this -> assertIdentical($objController -> getView(), $objView);

			$objTranslator = new DefaultTranslator('en');
			$objController -> useTranslator($objTranslator);
			$this -> assertIdentical($objController -> getTranslator(), $objTranslator);
		}


		public function testDefaultFiles() {

			// create controller instance
			$objController = $this -> getMVCController();

			// test default language file
			$sExpectedLanguageFile = APPLICATION_ROOT .
							         TekunaApplication :: BASEDIR_LANGFILES .
							         'en-us' .
			                         DIRECTORY_SEPARATOR .
			                         'TestMVCController.ini';

			$this -> assertIdentical($objController -> getTranslator() -> getLanguageFile(), $sExpectedLanguageFile);


			// test default template
			$sExpectedBaseDir = APPLICATION_ROOT .
			                    TekunaApplication :: BASEDIR_COMPONENTS .
			                    'view' .
			                    DIRECTORY_SEPARATOR;

			$this -> assertIdentical($objController -> getView() -> getTemplateBaseDir(), $sExpectedBaseDir);
			$this -> assertIdentical($objController -> getView() -> getTemplate(), 'TestMVCController.tpl');

		}


		public function testDefaultImplementation() {

			// build mocked context
			$objRequest = new RequestMock();
			$objContext = $this -> buildContext();
			$objContext -> setRequest($objRequest);

			// get minimal controller instance
			$objController = new TestMinimalMVCController($objContext);

			// test GET request
			$objRequest -> setRequestMethod('GET');
			$this -> assertIdentical($objController -> getOutput(), 'display');

			// test POST request
			// this should call the display method, too
			$objRequest -> setRequestMethod('POST');
			$this -> assertIdentical($objController -> getOutput(), 'display');
		}


		public function testViewClassOverwriting() {

			// create default controller instance
			$objController = $this -> getMVCController();
			$this -> assertIdentical($objController -> getView(), new SimpleView());

			// create xslt controller instance
			$objXSLTController = $this -> getXSLTMVCController();

			// test default template
			$this -> assertIdentical($objXSLTController -> getView(), new XSLTView());
			$this -> assertIdentical($objXSLTController -> getView() -> getTemplate(), 'TestXSLTMVCController.xsl');

			// create php controller instance
			$objPHPController = $this -> getPHPMVCController();

			// test default template
			$this -> assertIdentical($objPHPController -> getView(), new PHPView());
			$this -> assertIdentical($objPHPController -> getView() -> getTemplate(), 'TestPHPMVCController.php');
		}


		public function testTranslationOverwriting() {

			// create default controller instance
			$objController = $this -> getMVCController();

			// check translated output
			$this -> assertIdentical($objController -> getOutput(), "testOutput\n");


			// create controller instance without i18n
			$objController2 = $this -> getMVCNoI18NController();

			// check translated output
			$this -> assertIdentical($objController2 -> getOutput(), "%test.key%\n");
		}


		public function testModelOverwriting() {

			// create default controller instance
			$objController = $this -> getMVCController();

			// test disabled model
			$this -> assertIdentical($objController -> getModel(), NULL);


			// create mvc controller with enabled model
			$objController2 = $this -> getMVCModelController();

			// test enabled model
			$this -> assertIdentical($objController2 -> getModel(), new TestMVCModelControllerModel());
		}


		public function testWorkflow() {

			// init context objects
			$objRequest = new RequestMock();
			$objContext = $this -> buildContext();
			$objContext -> setRequest($objRequest);

			// test display()
			$objRequest -> setRequestMethod('GET');
			$objController = new TestMVCDisplayController($objContext);
			$this -> assertIdentical($objController -> getOutput(), 'display');

			// test validate() with no success
			$objRequest -> setRequestMethod('POST');
			$objController = new TestMVCValidateFalseController($objContext);
			$this -> assertIdentical($objController -> getOutput(), 'error');

			// test validate() with success
			$objRequest -> setRequestMethod('POST');
			$objController = new TestMVCValidateTrueController($objContext);
			$this -> assertIdentical($objController -> getOutput(), 'store');

			// test validate() with default exception
			$objRequest -> setRequestMethod('POST');
			$objController = new TestMVCValidateFalseExceptionController($objContext);

			try {

				$objController -> getOutput();
				$this -> fail();
			}
			catch (ControllerValidationException $e) {

				$this -> pass();
			}

			// test redirect()
			$objRequest -> setRequestMethod('GET');
			$objController = new TestMVCRedirectSourceController($objContext);
			$this -> assertIdentical($objController -> getOutput(), 'TestMVCRedirectTargetController');
		}
	}



